/**
 * @author Administrator
 * @create 2021/11/23
 */
package com.myblog.aspect;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 *@author Qin xike
 *@date 2021/11/23 12:17
 */
@Aspect
@Component
public class AutoStringAspect {

	// 通过 Pointcut 获取注解位置
	@Pointcut("@annotation(com.myblog.anotation.AutoString)")
	public void stringPointCut() {

	}

	// 增强处理
	@Around("stringPointCut()")
	public Object around(ProceedingJoinPoint point) throws Throwable {


		//获取参数值
		Object[] paramValues = point.getArgs();
		for (Object arg : paramValues) {

			//获取类的字段
			Field[] fields = arg.getClass().getDeclaredFields();
			for (Field field : fields) {

				// 设置字段可访问， 否则无法访问private修饰的变量值
				field.setAccessible(true);

				//获取字段名
				String name = field.getName();
				// 获取字段类型
				String type = field.getGenericType().toString();

				// 拼装get set方法  例如 setName getName
				String setMethodName = "set" + name.substring(0,1).toUpperCase()+name.substring(1);
				String getMethodName = "get" + name.substring(0,1).toUpperCase()+name.substring(1);


				//通过方法名称获取对应的方法，这里是获取字段的get方法
				Method getMethod = arg.getClass().getMethod(getMethodName);

				// 判断类型是string 类型
				if ("class java.lang.String".equals(type)) {

					// 获取set方法
					Method setMethod = arg.getClass().getMethod(setMethodName, String.class);
					// 通过 invoke 获取到get方法的Value值  PS: invoke()方法就是用来执行指定对象的方法
					String value = (String) getMethod.invoke(arg);
					// 再invoke 执行 set方法  StringUtils.trim 对空格进行处理
					setMethod.invoke(arg, StringUtils.trim(value));
				}

				// 判断类型是List<String> 类型
				if ("java.util.List<java.lang.String>".equals(type)) {

					Method setMethod = arg.getClass().getMethod(setMethodName, List.class);
					List<String> valueList = (List<String>) getMethod.invoke(arg);
					// 通过java 8 对集合中的值进行处理 ，java8 中 “：：” 就是调用方法的意思
					List<String> collect = valueList.stream().map(StringUtils::trim).collect(Collectors.toList());
					setMethod.invoke(arg, collect);

				}
			}
		}

		return point.proceed();
	}

}
